package ui;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

import javax.swing.AbstractListModel;

import workers.TimedWorker;

@SuppressWarnings("serial")
public class TimeWorkerListModel extends AbstractListModel implements PropertyChangeListener, Runnable {
	
	private List<TimedWorker> elements; 
	private List<PropertyChangeEvent> changes;
	private boolean update = true;
	public TimeWorkerListModel(){
		elements = Collections.synchronizedList(new ArrayList<TimedWorker>());
		changes = Collections.synchronizedList(new LinkedList<PropertyChangeEvent>());

		Thread t = new Thread( this );
		t.start();
	}
	
	public long calcularTiempoPromedio(){
		synchronized( elements ){
			int tam = elements.size();
			if( tam > 0 ){
				tam = 0;
				long tiempoTotal = 0;
				for (TimedWorker wts : elements) {				
					if( !wts.isWorking() ){
						tiempoTotal += wts.getStopWatch().getElapsedTime();
						tam ++;
					}
				}
				if( tam > 0 ){
					tiempoTotal /= tam;
				}
				return tiempoTotal;
				//labelPromedio.setText( "Tiempo promedio por operacion:  " + Long.toString(tiempoTotal) + "ms "  );
			}
			return 0;
		}
	}

	@Override
	public Object getElementAt(int index) {
		return elements.get(index);
	}

	@Override
	public int getSize() {
		return elements.size();
	}

	public void clearFinishedTasks(){
		synchronized( elements ){
			for ( int i = 0; i< elements.size() ; ) {
				TimedWorker wts = elements.get(i);
				if( !wts.isWorking()) {
					elements.remove(i);
				}
				else{
					i++;
				}
			}
			fireContentsChanged(this, 0, elements.size());
		}
	}

	public void add( TimedWorker worker ){
		synchronized( elements ){
			elements.add(worker);
			fireIntervalAdded(this, elements.size()-1, elements.size());
		}
	}

	@Override
	public void propertyChange(PropertyChangeEvent evt) {
		changes.add(evt);
	}
	
	public void updateChanges(){
		synchronized( changes ){
			for (PropertyChangeEvent evt : changes) {
				int index0 = elements.indexOf(evt.getSource());
				if(index0>=0)fireContentsChanged(this, index0, index0+1);
			}
		}
	}
	
	public void run(){
		while(update){
			updateChanges();
			try { Thread.sleep(500); } catch (InterruptedException ignore) {}
		}
	}
}